﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Data.Common;
using System.IO;
using System.Linq;
using Assist;
using Autodesk.Revit.DB;
using Autodesk.Revit.DB.ExtensibleStorage;
using Autodesk.Revit.UI;
using DataBase;
using DBService;
using YArchitech.Controls;
using HYFamilyLibDataManager;

namespace YArchitech.Revit.MEP.Opening
{
	public abstract class DbOpeningBase
	{
		[Browsable(false)]
		[Category("属性")]
		[Description("开洞主体Id")]
		[DisplayName("开洞主体Id")]
		[ReadOnly(true)]
		public int HostId
		{
			get
			{
				return this.mHostId;
			}
			set
			{
				this.mHostId = value;
			}
		}

		[Browsable(false)]
		public int PipeId
		{
			get
			{
				return this.mPipeId;
			}
			set
			{
				this.mPipeId = value;
			}
		}

		protected BoxParameter OpeningParameter
		{
			get
			{
				if (this.mParameter.SectionType == DBService.SectionType.Arc)
				{
					return new BoxParameter(this.mParameter.Parameter1 + this.BoxParameter.Parameter1);
				}
				return new BoxParameter(this.mParameter.Parameter1 / 2.0 + this.BoxParameter.Parameter1, this.mParameter.Parameter1 / 2.0 + this.BoxParameter.Parameter2, this.mParameter.Parameter2 / 2.0 + this.BoxParameter.Parameter3, this.mParameter.Parameter2 / 2.0 + this.BoxParameter.Parameter4);
			}
		}

		public void SetDate(Element element)
		{
			try
			{
				if (element != null)
				{
					List<SchemaData> list = new List<SchemaData>();
					SchemaData item = new SchemaData("OpeningDate", typeof(string));
					list.Add(item);
					EntityUtils.CreateSchema(DbOpeningBase.OpeningAppGuid, "HyOpening", list);
					EntityUtils.SetValueString(element, DbOpeningBase.OpeningAppGuid, "OpeningDate", this.Date.ToString());
				}
			}
			catch
			{
			}
		}

		public static DateTime GetDate(Element elem)
		{
			DateTime result;
			DateTime.TryParse(EntityUtils.GetValueString(elem, DbOpeningBase.OpeningAppGuid, "OpeningDate"), out result);
			return result;
		}

		[Browsable(false)]
		public HostType HostType { get; set; }

		[DisplayName("是否开洞")]
		public bool IsOpened
		{
			get
			{
				return this.Status == OpeningStatus.Opened;
			}
			set
			{
				this.Status = (value ? OpeningStatus.Opened : OpeningStatus.Unopen);
			}
		}

		[DisplayName("建筑主体")]
		[ReadOnly(true)]
		public string HostTypeString
		{
			get
			{
				if (this.HostType == HostType.eArchWall)
				{
					return "建筑墙";
				}
				if (this.HostType == HostType.eStruWall)
				{
					return "结构墙";
				}
				if (this.HostType == HostType.eBeam)
				{
					return "梁";
				}
				return "楼板";
			}
		}

		[Browsable(false)]
		public CutType CutType { get; set; }

		[DisplayName("专业主体")]
		public string CutTypeString
		{
			get
			{
				if (this.CutType == CutType.eDuct)
				{
					return "风管";
				}
				if (this.CutType == CutType.ePipe)
				{
					return "水管";
				}
				if (this.CutType == CutType.eBridge)
				{
					return "桥架";
				}
				return "其他";
			}
		}

		[DisplayName("专业")]
		[Browsable(false)]
		public string MajorString
		{
			get
			{
				if (this.CutType == CutType.eDuct)
				{
					return "暖";
				}
				if (this.CutType == CutType.ePipe)
				{
					return "水";
				}
				if (this.CutType == CutType.eBridge)
				{
					return "电";
				}
				return "其他";
			}
		}

		[Browsable(false)]
		public IDatabase Database
		{
			get
			{
				return this.mDatabase;
			}
		}

		[Browsable(false)]
		public Guid Guid
		{
			get
			{
				return this.mGuid;
			}
			set
			{
				this.mGuid = value;
			}
		}

		[Browsable(false)]
		public string Level { get; set; }

		[DisplayName("楼层")]
		public string LevelString
		{
			get
			{
				return this.Level;
			}
		}

		[DisplayName("X")]
		[ReadOnly(true)]
		public string AxisX { get; set; }

		[DisplayName("Y")]
		[ReadOnly(true)]
		public string AxisY { get; set; }

		[DisplayName("当前项目")]
		public bool IsCurrentProject { get; set; }

		[Browsable(false)]
		public SectionParameter SectionParameter
		{
			get
			{
				return this.mParameter;
			}
			set
			{
				this.mParameter = value;
			}
		}

		[DisplayName("管道尺寸")]
		public string SectionParameterString
		{
			get
			{
				return this.GetSectionString();
			}
		}

		[DisplayName("套管类型")]
		[ReadOnly(true)]
		[Browsable(false)]
		public string DrivePipeTypeName
		{
			get
			{
				return this.m_strDrivePipeTypeName;
			}
			set
			{
				this.m_strDrivePipeTypeName = value;
			}
		}

		[Browsable(false)]
		public BoxParameter BoxParameter { get; set; }

		[DisplayName("外扩尺寸")]
		public string BoxParameterString
		{
			get
			{
				return this.BoxParameter.ToString();
			}
			set
			{
				double parameter = 0.0;
				try
				{
					parameter = Convert.ToDouble(value);
				}
				catch
				{
				}
				this.BoxParameter.Parameter1 = (this.BoxParameter.Parameter2 = (this.BoxParameter.Parameter3 = (this.BoxParameter.Parameter4 = parameter)));
			}
		}

		[Browsable(false)]
		public string ArchPath
		{
			get
			{
				return DbProject.GetFromDB(this.mProjectId, this.mDatabase).RacFilePath;
			}
		}

		[Browsable(false)]
		public string MepPath
		{
			get
			{
				return DbProject.GetFromDB(this.mProjectId, this.mDatabase).RmeFilePath;
			}
		}

		[Category("属性")]
		[Description("开洞状态:1.Opened表示已开 2.Unopen表示未开 3.Invalid表示不需要开")]
		[DisplayName("开洞状态")]
		[Browsable(false)]
		public OpeningStatus Status
		{
			get
			{
				return this.mStatus;
			}
			set
			{
				this.mStatus = value;
			}
		}

		[DisplayName("开洞状态")]
		[Browsable(false)]
		public string OpeningStatusString
		{
			get
			{
				if (this.mStatus == OpeningStatus.Opened)
				{
					return "已开";
				}
				if (this.mStatus == OpeningStatus.Unopen)
				{
					return "未开";
				}
				return "不开";
			}
		}

		[Browsable(false)]
		public string Remark { get; set; }

		[DisplayName("日期")]
		[ReadOnly(true)]
		public DateTime Date { get; set; }

		[DisplayName("备注")]
		public string RemarkString
		{
			get
			{
				return this.Remark;
			}
			set
			{
				this.Remark = value;
			}
		}

		[Browsable(false)]
		public XYZ Location
		{
			get
			{
				return this.mPt;
			}
			set
			{
				this.mPt = value;
			}
		}

		[Browsable(false)]
		public bool IsPrimaryStructureOpening { get; set; }

		[Browsable(false)]
		public string MEPFileName { get; set; }

		[Browsable(false)]
		public ElementId OpeningID { get; set; }

		[Browsable(false)]
		public XYZ PipeStartPoint { get; set; }

		[Browsable(false)]
		public XYZ PipeEndPoint { get; set; }

		[Browsable(false)]
		public double PipeConnAxisXOnSectionPlaneAng { get; set; }

		public override bool Equals(object obj)
		{
			if (obj == null)
			{
				return false;
			}
			if (obj is DbWallToBeOpened)
			{
				return ((DbWallToBeOpened)obj).Equals(this);
			}
			if (obj is DbFloorToBeOpened)
			{
				return ((DbFloorToBeOpened)obj).Equals(this);
			}
			return obj is DbOpeningBase && ((DbOpeningBase)obj).Guid.Equals(this.Guid);
		}

		public override string ToString()
		{
			string str = "";
			if (this.Status == OpeningStatus.Opened)
			{
				str = "已开";
			}
			else if (this.Status == OpeningStatus.Unopen)
			{
				str = "未开";
			}
			else if (this.Status == OpeningStatus.Invalid)
			{
				str = "不开";
			}
			return this.mParameter.ToString() + "-" + str;
		}

		public static List<FamilyInstance> FindAllOpening(Autodesk.Revit.DB.Document doc)
		{
			IEnumerable<Element> enumerable = new FilteredElementCollector(doc).OfClass(typeof(FamilyInstance)).ToElements();
			List<FamilyInstance> list = new List<FamilyInstance>();
			foreach (Element element in enumerable)
			{
				if (DbOpeningBase.GetDate(element) != default(DateTime))
				{
					list.Add(element as FamilyInstance);
				}
			}
			return list;
		}

		public static List<FamilyInstance> FindOpening(Autodesk.Revit.DB.Document doc, DateTime min, DateTime max)
		{
			min = min.AddHours((double)(-(double)min.Hour));
			max = max.AddHours((double)(24 - max.Hour));
			IEnumerable<Element> enumerable = new FilteredElementCollector(doc).OfClass(typeof(FamilyInstance)).ToElements();
			List<FamilyInstance> list = new List<FamilyInstance>();
			foreach (Element element in enumerable)
			{
				DateTime date = DbOpeningBase.GetDate(element);
				if (date != default(DateTime) && date >= min && date <= max)
				{
					list.Add(element as FamilyInstance);
				}
			}
			return list;
		}

		public static void ClearTag(Autodesk.Revit.DB.Document doc)
		{
			DbOpeningBase.clearBeamOpeningTag(doc);
			DbOpeningBase.clearWallOpeningTag(doc);
			DbOpeningBase.clearFloorOpeningTag(doc);
		}

		private static void clearBeamOpeningTag(Autodesk.Revit.DB.Document doc)
		{
            IList<Element> list = new FilteredElementCollector(doc).OfClass(typeof(Autodesk.Revit.DB.Opening)).ToElements();
			Transaction transaction = new Transaction(doc, "ClearBeamTag");
			try
			{
				transaction.Start();
				foreach (Element element in list)
				{
					try
					{
						Guid guid = default(Guid);
						bool flag = false;
						DbOpeningBase.ReadData(element, ref guid, ref flag);
						if (flag)
						{
							doc.Delete(element.Id);
						}
					}
					catch (Exception)
					{
					}
				}
				transaction.Commit();
			}
			catch
			{
				transaction.RollBack();
			}
		}

		private static void clearFloorOpeningTag(Autodesk.Revit.DB.Document doc)
		{
			IList<Element> list = new FilteredElementCollector(doc).OfClass(typeof(GroupType)).ToElements();
			Transaction transaction = new Transaction(doc, "ClearFloorTag");
			try
			{
				transaction.Start();
				foreach (Element element in list)
				{
					if ((element as GroupType).Name.IndexOf("协同开洞标记_") > -1)
					{
						try
						{
							doc.Delete(element.Id);
						}
						catch (Exception)
						{
						}
					}
				}
				transaction.Commit();
			}
			catch
			{
				transaction.RollBack();
			}
		}

		private static void clearWallOpeningTag(Autodesk.Revit.DB.Document doc)
		{
			DbOpeningBase.clearFloorOpeningTag(doc);
		}

		private BoundingBoxUV GetPolygon(Transform transform, UIApplication uiApp, double exLength)
		{
			BoundingBoxUV result = new BoundingBoxUV();
			XYZ xyz = DbOpeningBase.TransformPoint(this.Location, transform.Inverse);
			if (this.BoxParameter.SectionType == DBService.SectionType.Arc)
			{
				double num = AssistFunc.mmToFeet(this.BoxParameter.Parameter1 + this.SectionParameter.Parameter1 + exLength);
				XYZ xyz2 = new XYZ(xyz.X - num, xyz.Y - num, xyz.Z);
				XYZ xyz3 = new XYZ(xyz.X + num, xyz.Y + num, xyz.Z);
				result = new BoundingBoxUV(xyz2.X, xyz2.Y, xyz3.X, xyz3.Y);
			}
			else
			{
				double num2 = AssistFunc.mmToFeet(this.BoxParameter.Parameter1 + this.SectionParameter.Parameter1 / 2.0 + exLength);
				double num3 = AssistFunc.mmToFeet(this.BoxParameter.Parameter2 + this.SectionParameter.Parameter1 / 2.0 + exLength);
				double num4 = AssistFunc.mmToFeet(this.BoxParameter.Parameter3 + this.SectionParameter.Parameter2 / 2.0 + exLength);
				double num5 = AssistFunc.mmToFeet(this.BoxParameter.Parameter4 + this.SectionParameter.Parameter2 / 2.0 + exLength);
				new XYZ(xyz.X - num4, xyz.Y + num2, xyz.Z);
				XYZ xyz4 = new XYZ(xyz.X + num5, xyz.Y + num2, xyz.Z);
				new XYZ(xyz.X + num5, xyz.Y - num3, xyz.Z);
				XYZ xyz5 = new XYZ(xyz.X - num4, xyz.Y - num3, xyz.Z);
				result = new BoundingBoxUV(xyz5.X, xyz5.Y, xyz4.X, xyz4.Y);
			}
			return result;
		}

		public static Element FindTag(DbOpeningBase dob, Autodesk.Revit.DB.Document doc)
		{
			Element result = null;
			foreach (Group group in ((IEnumerable<Group>)new FilteredElementCollector(doc).OfClass(typeof(Group)).Cast<Group>().ToList<Group>()))
			{
				try
				{
					if (group.GroupType.Name == "协同开洞标记_" + dob.Guid.ToString())
					{
						result = group;
						break;
					}
				}
				catch (Exception)
				{
				}
			}
			return result;
		}

		public static void ClearFromDbByProject(DbProject project)
		{
			try
			{
				if (project.Database.Connection.State == ConnectionState.Closed)
				{
					project.Database.Connection.Open();
				}
				DbCommand dbCommand = project.Database.Connection.CreateCommand();
				dbCommand.CommandText = string.Format("DELETE FROM tbSynergyOpiening WHERE ProjectId = {0}", project.Id);
				dbCommand.ExecuteNonQuery();
				if (project.Database.Connection.State == ConnectionState.Open)
				{
					project.Database.Connection.Close();
				}
			}
			catch (Exception ex)
			{
				if (project.Database.Connection.State == ConnectionState.Open)
				{
					project.Database.Connection.Close();
				}
				throw ex;
			}
		}

		public virtual void AddToDb(IDatabase db)
		{
			try
			{
				if (db.Connection.State == ConnectionState.Closed)
				{
					db.Connection.Open();
				}
				DbCommand dbCommand = db.Connection.CreateCommand();
				string commandText = string.Format("INSERT INTO tbSynergyOpiening (ProjectId,HostId,PtX,PtY,PtZ,Parameter1,Parameter2,SectionType,Status,Guid,BoxParameter1,BoxParameter2,BoxParameter3,BoxParameter4,Level,CutType,HostType,BoxSectionType,PipeId,Remark) VALUES ({0},{1},{2},{3},{4},{5},{6},{7},{8},'{9}',{10},{11},{12},{13},'{14}',{15},{16},{17},{18},'{19}')", new object[]
				{
					this.mProjectId,
					this.HostId,
					this.mPt.X,
					this.mPt.Y,
					this.mPt.Z,
					this.mParameter.Parameter1,
					this.mParameter.Parameter2,
					(int)this.mParameter.SectionType,
					(int)this.Status,
					this.Guid.ToString(),
					this.BoxParameter.Parameter1,
					this.BoxParameter.Parameter2,
					this.BoxParameter.Parameter3,
					this.BoxParameter.Parameter4,
					this.Level,
					(int)this.CutType,
					(int)this.HostType,
					(int)this.BoxParameter.SectionType,
					this.PipeId,
					this.Remark
				});
				dbCommand.CommandText = commandText;
				dbCommand.ExecuteNonQuery();
				this.mDatabase = db;
				if (db.Connection.State == ConnectionState.Open)
				{
					db.Connection.Close();
				}
			}
			catch (Exception ex)
			{
				if (db.Connection.State == ConnectionState.Open)
				{
					db.Connection.Close();
				}
				throw ex;
			}
		}

		public virtual void WirteToXML(string fileName)
		{
		}

		public virtual void UpdateToDb()
		{
			try
			{
				if (this.Database.Connection.State == ConnectionState.Closed)
				{
					this.Database.Connection.Open();
				}
				DbCommand dbCommand = this.Database.Connection.CreateCommand();
				dbCommand.CommandText = string.Format("UPDATE tbSynergyOpiening SET ProjectId={0},HostId={1},PtX={2},PtY={3},PtZ={4},Parameter1={5},Parameter2={6},SectionType={7},Status={8},BoxParameter1={9},BoxParameter2={10},BoxParameter3={11},BoxParameter4={12},Level='{13}',CutType={14},HostType={15},BoxSectionType={16},Remark='{17}' WHERE Guid ='{18}'", new object[]
				{
					this.mProjectId,
					this.mHostId,
					this.mPt.X,
					this.mPt.Y,
					this.mPt.Z,
					this.mParameter.Parameter1,
					this.mParameter.Parameter2,
					(int)this.mParameter.SectionType,
					(int)this.Status,
					this.BoxParameter.Parameter1,
					this.BoxParameter.Parameter2,
					this.BoxParameter.Parameter3,
					this.BoxParameter.Parameter4,
					this.Level,
					(int)this.CutType,
					(int)this.HostType,
					(int)this.BoxParameter.SectionType,
					this.Remark,
					this.Guid.ToString()
				});
				dbCommand.ExecuteNonQuery();
				if (this.Database.Connection.State == ConnectionState.Open)
				{
					this.Database.Connection.Close();
				}
			}
			catch (Exception ex)
			{
				if (this.Database.Connection.State == ConnectionState.Open)
				{
					this.Database.Connection.Close();
				}
				throw ex;
			}
		}

		public virtual void RemoveFromDb()
		{
			try
			{
				if (this.Database.Connection.State == ConnectionState.Closed)
				{
					this.Database.Connection.Open();
				}
				DbCommand dbCommand = this.Database.Connection.CreateCommand();
				dbCommand.CommandText = string.Format("DELETE FROM tbSynergyOpiening WHERE Guid = '{0}'", this.Guid.ToString());
				dbCommand.ExecuteNonQuery();
				if (this.Database.Connection.State == ConnectionState.Open)
				{
					this.Database.Connection.Close();
				}
			}
			catch (Exception ex)
			{
				if (this.Database.Connection.State == ConnectionState.Open)
				{
					this.Database.Connection.Close();
				}
				throw ex;
			}
		}

		public virtual void UpdateToXML(string fileName)
		{
		}

		public virtual void AddOpeningTag(UIApplication uiApp, TagStyle ts)
		{
		}

		public virtual Element Create(UIApplication uiApp)
		{
			return null;
		}

		public virtual void RemoveOpeningTag(Autodesk.Revit.DB.Document doc)
		{
			Element element = DbOpeningBase.FindTag(this, doc);
			if (element != null)
			{
				Transaction transaction = new Transaction(doc, "DelTag");
				transaction.Start();
				try
				{
					doc.Delete(element.Id);
					transaction.Commit();
				}
				catch (Exception)
				{
					transaction.RollBack();
				}
			}
		}

		public virtual void UpdateTag(UIApplication uiApp, TagStyle ts)
		{
			Document document = uiApp.ActiveUIDocument.Document;
			this.RemoveOpeningTag(document);
			this.AddOpeningTag(uiApp, ts);
		}

		public static XYZ Midpoint(XYZ pt1, XYZ pt2)
		{
			return new XYZ((pt1.X + pt2.X) / 2.0, (pt1.Y + pt2.Y) / 2.0, (pt1.Z + pt2.Z) / 2.0);
		}

		public static XYZ TransformPoint(XYZ point, Transform transform)
		{
			double x = point.X;
			double y = point.Y;
			double z = point.Z;
			XYZ xyz = transform.get_Basis(0);
			XYZ xyz2 = transform.get_Basis(1);
			XYZ xyz3 = transform.get_Basis(2);
			XYZ origin = transform.Origin;
			double num = x * xyz.X + y * xyz2.X + z * xyz3.X + origin.X;
			double num2 = x * xyz.Y + y * xyz2.Y + z * xyz3.Y + origin.Y;
			double num3 = x * xyz.Z + y * xyz2.Z + z * xyz3.Z + origin.Z;
			return new XYZ(num, num2, num3);
		}

		private static bool ListEquals(List<DbOpeningBase> list1, List<DbOpeningBase> list2)
		{
			bool result = false;
			if (list1.Count == list2.Count)
			{
				result = true;
				foreach (DbOpeningBase item in list1)
				{
					if (!list2.Contains(item))
					{
						result = false;
					}
				}
			}
			return result;
		}

		public static List<DbOpeningBase> Combine(List<DbOpeningBase> oList, UIApplication uiApp, double size, double exLenght, bool isBox)
		{
			List<List<DbOpeningBase>> list = new List<List<DbOpeningBase>>();
			Document document = uiApp.ActiveUIDocument.Document;
			List<LinkFile> linkFiles = LinkFile.GetLinkFiles(document);
			foreach (DbOpeningBase dbOpeningBase in oList)
			{
				if (dbOpeningBase.CutType == CutType.eOther)
				{
					bool flag = false;
					using (List<List<DbOpeningBase>>.Enumerator enumerator2 = list.GetEnumerator())
					{
						while (enumerator2.MoveNext())
						{
							if (enumerator2.Current.Contains(dbOpeningBase))
							{
								flag = true;
								break;
							}
						}
					}
					if (!flag)
					{
						list.Add(new List<DbOpeningBase>
						{
							dbOpeningBase
						});
					}
				}
				else
				{
					foreach (DbOpeningBase dbOpeningBase2 in oList)
					{
						if (dbOpeningBase2.CutType == CutType.eOther)
						{
							bool flag2 = false;
							using (List<List<DbOpeningBase>>.Enumerator enumerator2 = list.GetEnumerator())
							{
								while (enumerator2.MoveNext())
								{
									if (enumerator2.Current.Contains(dbOpeningBase2))
									{
										flag2 = true;
										break;
									}
								}
							}
							if (!flag2)
							{
								list.Add(new List<DbOpeningBase>
								{
									dbOpeningBase2
								});
							}
						}
						else
						{
							Type type = dbOpeningBase.GetType();
							Type type2 = dbOpeningBase2.GetType();
							if (!dbOpeningBase.Equals(dbOpeningBase2) && type.Equals(type2))
							{
								if (dbOpeningBase is DbWallToBeOpened)
								{
									DbWallToBeOpened dbWallToBeOpened = (DbWallToBeOpened)dbOpeningBase;
									DbWallToBeOpened dbWallToBeOpened2 = (DbWallToBeOpened)dbOpeningBase2;
									if (dbWallToBeOpened2.HostId == dbWallToBeOpened.HostId)
									{
										ElementId elementId = new ElementId(dbWallToBeOpened.HostId);
										Wall wall = document.GetElement(elementId) as Wall;
										if (wall == null)
										{
											foreach (LinkFile linkFile in linkFiles)
											{
												document = uiApp.Application.OpenDocumentFile(linkFile.FileName);
												wall = (document.GetElement(elementId) as Wall);
												if (wall != null)
												{
													break;
												}
											}
										}
										if (wall != null)
										{
											Curve curve = (wall.Location as LocationCurve).Curve;
											Transform identity = Transform.Identity;
											identity.Origin = curve.GetEndPoint(0);
											identity.BasisX = (curve.GetEndPoint(1) - curve.GetEndPoint(0)).Normalize();
											identity.BasisY = XYZ.BasisZ.Normalize();
											identity.BasisZ = identity.BasisX.CrossProduct(identity.BasisY);
											if (!BoundingBoxUtils.UnIntersect(dbWallToBeOpened.GetPolygon(identity, uiApp, size / 2.0), dbWallToBeOpened2.GetPolygon(identity, uiApp, size / 2.0)))
											{
												bool flag3 = false;
												foreach (List<DbOpeningBase> list2 in list)
												{
													if (list2.Contains(dbOpeningBase))
													{
														flag3 = true;
														bool flag4 = false;
														List<DbOpeningBase> item = new List<DbOpeningBase>();
														foreach (List<DbOpeningBase> list3 in list)
														{
															if (!DbOpeningBase.ListEquals(list2, list3) && list3.Contains(dbOpeningBase2))
															{
																item = list3;
																list2.AddRange(list3);
																flag4 = true;
																break;
															}
														}
														if (flag4)
														{
															list.Remove(item);
															break;
														}
														if (!list2.Contains(dbOpeningBase2))
														{
															list2.Add(dbOpeningBase2);
															break;
														}
														break;
													}
												}
												if (!flag3)
												{
													list.Add(new List<DbOpeningBase>
													{
														dbOpeningBase,
														dbOpeningBase2
													});
												}
											}
											else
											{
												bool flag5 = false;
												bool flag6 = false;
												foreach (List<DbOpeningBase> list4 in list)
												{
													if (list4.Contains(dbOpeningBase))
													{
														flag5 = true;
													}
													if (list4.Contains(dbOpeningBase2))
													{
														flag6 = true;
													}
												}
												List<DbOpeningBase> list5 = new List<DbOpeningBase>();
												List<DbOpeningBase> list6 = new List<DbOpeningBase>();
												if (!flag5)
												{
													list5.Add(dbOpeningBase);
													list.Add(list5);
												}
												if (!flag6)
												{
													list6.Add(dbOpeningBase2);
													list.Add(list6);
												}
											}
										}
									}
									else
									{
										bool flag7 = false;
										bool flag8 = false;
										foreach (List<DbOpeningBase> list7 in list)
										{
											if (list7.Contains(dbOpeningBase))
											{
												flag7 = true;
											}
											if (list7.Contains(dbOpeningBase2))
											{
												flag8 = true;
											}
										}
										List<DbOpeningBase> list8 = new List<DbOpeningBase>();
										List<DbOpeningBase> list9 = new List<DbOpeningBase>();
										if (!flag7)
										{
											list8.Add(dbOpeningBase);
											list.Add(list8);
										}
										if (!flag8)
										{
											list9.Add(dbOpeningBase2);
											list.Add(list9);
										}
									}
								}
								else
								{
									DbFloorToBeOpened dbFloorToBeOpened = (DbFloorToBeOpened)dbOpeningBase;
									DbFloorToBeOpened dbFloorToBeOpened2 = (DbFloorToBeOpened)dbOpeningBase2;
									if (dbFloorToBeOpened2.HostId == dbFloorToBeOpened.HostId)
									{
										Transform identity2 = Transform.Identity;
										if (!BoundingBoxUtils.UnIntersect(dbFloorToBeOpened.GetPolygon(identity2, uiApp, size / 2.0), dbFloorToBeOpened2.GetPolygon(identity2, uiApp, size / 2.0)))
										{
											bool flag9 = false;
											foreach (List<DbOpeningBase> list10 in list)
											{
												if (list10.Contains(dbOpeningBase))
												{
													flag9 = true;
													bool flag10 = false;
													List<DbOpeningBase> item2 = new List<DbOpeningBase>();
													foreach (List<DbOpeningBase> list11 in list)
													{
														if (!DbOpeningBase.ListEquals(list10, list11) && list11.Contains(dbOpeningBase2))
														{
															item2 = list11;
															list10.AddRange(list11);
															flag10 = true;
															break;
														}
													}
													if (flag10)
													{
														list.Remove(item2);
														break;
													}
													if (!list10.Contains(dbOpeningBase2))
													{
														list10.Add(dbOpeningBase2);
														break;
													}
													break;
												}
											}
											if (!flag9)
											{
												list.Add(new List<DbOpeningBase>
												{
													dbOpeningBase,
													dbOpeningBase2
												});
											}
										}
										else
										{
											bool flag11 = false;
											bool flag12 = false;
											foreach (List<DbOpeningBase> list12 in list)
											{
												if (list12.Contains(dbOpeningBase))
												{
													flag11 = true;
												}
												if (list12.Contains(dbOpeningBase2))
												{
													flag12 = true;
												}
											}
											List<DbOpeningBase> list13 = new List<DbOpeningBase>();
											List<DbOpeningBase> list14 = new List<DbOpeningBase>();
											if (!flag11)
											{
												list13.Add(dbOpeningBase);
												list.Add(list13);
											}
											if (!flag12)
											{
												list14.Add(dbOpeningBase2);
												list.Add(list14);
											}
										}
									}
									else
									{
										bool flag13 = false;
										bool flag14 = false;
										foreach (List<DbOpeningBase> list15 in list)
										{
											if (list15.Contains(dbOpeningBase))
											{
												flag13 = true;
											}
											if (!list15.Contains(dbOpeningBase2))
											{
												flag14 = true;
											}
										}
										List<DbOpeningBase> list16 = new List<DbOpeningBase>();
										List<DbOpeningBase> list17 = new List<DbOpeningBase>();
										if (!flag13)
										{
											list16.Add(dbOpeningBase);
											list.Add(list16);
										}
										if (!flag14)
										{
											list17.Add(dbOpeningBase2);
											list.Add(list17);
										}
									}
								}
							}
						}
					}
				}
			}
			List<DbOpeningBase> list18 = new List<DbOpeningBase>();
			foreach (List<DbOpeningBase> oList2 in list)
			{
				list18.Add(DbOpeningBase.CombineList(oList2, uiApp, exLenght, isBox));
			}
			return list18;
		}

		public static bool LessThan(double val1, double val2)
		{
			return val1 - val2 < -1E-09;
		}

		public static bool GreaterThan(double val1, double val2)
		{
			return val1 - val2 > 1E-09;
		}

		public static void SortReportsByDisplayOrder(ref BindingList<DbOpeningBase> reportList)
		{
			BindingList<DbOpeningBase> bindingList = new BindingList<DbOpeningBase>();
			BindingList<DbOpeningBase> bindingList2 = new BindingList<DbOpeningBase>();
			foreach (DbOpeningBase dbOpeningBase in reportList)
			{
				if (dbOpeningBase.IsCurrentProject)
				{
					bindingList.Add(dbOpeningBase);
				}
				else
				{
					bindingList2.Add(dbOpeningBase);
				}
			}
			reportList.Clear();
			foreach (DbOpeningBase item in bindingList)
			{
				reportList.Add(item);
			}
			foreach (DbOpeningBase item2 in bindingList2)
			{
				reportList.Add(item2);
			}
		}

		public static DbOpeningBase CombineList(List<DbOpeningBase> oList, UIApplication uiApp, double exLenght, bool isBox)
		{
			DbOpeningBase result;
			try
			{
				if (oList.Count > 1)
				{
					Document document = uiApp.ActiveUIDocument.Document;
					List<LinkFile> linkFiles = LinkFile.GetLinkFiles(document);
					if (oList[0] is DbWallToBeOpened)
					{
						ElementId elementId = new ElementId(((DbWallToBeOpened)oList[0]).HostId);
						Wall wall = document.GetElement(elementId) as Wall;
						if (wall == null)
						{
							foreach (LinkFile linkFile in linkFiles)
							{
								document = uiApp.Application.OpenDocumentFile(linkFile.FileName);
								wall = (document.GetElement(elementId) as Wall);
								if (wall != null)
								{
									break;
								}
							}
						}
						if (wall == null)
						{
							throw new Exception("没有找到文档或链接文档中需要开洞的墙。");
						}
						Curve curve = (wall.Location as LocationCurve).Curve;
						Transform identity = Transform.Identity;
						identity.Origin = curve.GetEndPoint(0);
						identity.BasisX = (curve.GetEndPoint(1) - curve.GetEndPoint(0)).Normalize();
						identity.BasisY = XYZ.BasisZ.Normalize();
						identity.BasisZ = identity.BasisX.CrossProduct(identity.BasisY);
						List<XYZ> list = new List<XYZ>();
						foreach (DbOpeningBase dbOpeningBase in oList)
						{
							XYZ xyz = DbOpeningBase.TransformPoint(dbOpeningBase.Location, identity.Inverse);
							Plane plane = RevitVersionFuncs.CreatePlanByNormalAndOrigin(XYZ.BasisZ, xyz);
							if (dbOpeningBase.BoxParameter.SectionType == DBService.SectionType.Arc)
							{
								BoxParameter boxParameter = new BoxParameter(dbOpeningBase.SectionParameter.Parameter1);
								Curve curve2 = uiApp.ActiveUIDocument.Document.CreatYJKArc(plane, AssistFunc.mmToFeet(boxParameter.Parameter1), 0.0, Math.PI*2);
								list.AddRange(curve2.Tessellate());
							}
							else
							{
								XYZ xyz2 = new XYZ(xyz.X - AssistFunc.mmToFeet(dbOpeningBase.SectionParameter.Parameter2 / 2.0), xyz.Y + AssistFunc.mmToFeet(dbOpeningBase.SectionParameter.Parameter1 / 2.0), xyz.Z);
								XYZ xyz3 = new XYZ(xyz.X + AssistFunc.mmToFeet(dbOpeningBase.SectionParameter.Parameter2 / 2.0), xyz.Y + AssistFunc.mmToFeet(dbOpeningBase.SectionParameter.Parameter1 / 2.0), xyz.Z);
								XYZ xyz4 = new XYZ(xyz.X + AssistFunc.mmToFeet(dbOpeningBase.SectionParameter.Parameter2 / 2.0), xyz.Y - AssistFunc.mmToFeet(dbOpeningBase.SectionParameter.Parameter1 / 2.0), xyz.Z);
								XYZ xyz5 = new XYZ(xyz.X - AssistFunc.mmToFeet(dbOpeningBase.SectionParameter.Parameter2 / 2.0), xyz.Y - AssistFunc.mmToFeet(dbOpeningBase.SectionParameter.Parameter1 / 2.0), xyz.Z);
								Line line = uiApp.ActiveUIDocument.Document.CreatYJKLine(xyz5, xyz2, true);
								Line line2 = uiApp.ActiveUIDocument.Document.CreatYJKLine(xyz2, xyz3, true);
								Line line3 = uiApp.ActiveUIDocument.Document.CreatYJKLine(xyz3, xyz4, true);
								Line line4 = uiApp.ActiveUIDocument.Document.CreatYJKLine(xyz4, xyz5, true);
								list.AddRange(line.Tessellate());
								list.AddRange(line2.Tessellate());
								list.AddRange(line3.Tessellate());
								list.AddRange(line4.Tessellate());
							}
						}
						XYZ xyz6 = list[0];
						XYZ xyz7 = list[0];
						double x = xyz6.X;
						double y = xyz6.Y;
						double x2 = xyz7.X;
						double y2 = xyz7.Y;
						foreach (XYZ xyz8 in list)
						{
							if (DbOpeningBase.LessThan(xyz8.X, x))
							{
								x = xyz8.X;
							}
							if (DbOpeningBase.LessThan(xyz8.Y, y))
							{
								y = xyz8.Y;
							}
							if (DbOpeningBase.GreaterThan(xyz8.X, x2))
							{
								x2 = xyz8.X;
							}
							if (DbOpeningBase.GreaterThan(xyz8.Y, y2))
							{
								y2 = xyz8.Y;
							}
						}
						xyz6 = new XYZ(x, y, xyz6.Z);
						xyz7 = new XYZ(x2, y2, xyz7.Z);
						XYZ xyz9 = DbOpeningBase.TransformPoint(DbOpeningBase.Midpoint(xyz6, xyz7), identity);
						BoxParameter bp;
						if (isBox)
						{
							double num = (double)((int)AssistFunc.feetToMM(xyz7.Y - xyz6.Y) / 2) + exLenght;
							double num2 = (double)((int)AssistFunc.feetToMM(xyz7.X - xyz6.X) / 2) + exLenght;
							bp = new BoxParameter(num, num, num2, num2);
						}
						else
						{
							bp = new BoxParameter((double)((int)AssistFunc.feetToMM(xyz6.DistanceTo(xyz7)) / 2) + exLenght);
						}
						result = new DbWallToBeOpened(uiApp.ActiveUIDocument.Document, oList[0].mProjectId, xyz9, elementId.IntegerValue, -1, new SectionParameter(0.0, 0.0), bp, CutType.eOther, HostType.eArchWall, oList[0].Level)
						{
							MEPFileName = oList[0].MEPFileName,
							PipeEndPoint = xyz9 - wall.Orientation,
							PipeStartPoint = xyz9 + wall.Orientation
						};
					}
					else
					{
						ElementId elementId2 = new ElementId(((DbFloorToBeOpened)oList[0]).HostId);
						document.GetElement(elementId2);
						Transform identity2 = Transform.Identity;
						List<XYZ> list2 = new List<XYZ>();
						foreach (DbOpeningBase dbOpeningBase2 in oList)
						{
							XYZ xyz10 = DbOpeningBase.TransformPoint(dbOpeningBase2.Location, identity2);
							Plane plane2 = RevitVersionFuncs.CreatePlanByNormalAndOrigin(XYZ.BasisZ, xyz10);
							if (dbOpeningBase2.BoxParameter.SectionType == DBService.SectionType.Arc)
							{
								BoxParameter boxParameter2 = new BoxParameter(dbOpeningBase2.SectionParameter.Parameter1);
								Curve curve3 = uiApp.ActiveUIDocument.Document.CreatYJKArc(plane2, AssistFunc.mmToFeet(boxParameter2.Parameter1), 0.0, Math.PI*2);
								list2.AddRange(curve3.Tessellate());
							}
							else
							{
								XYZ xyz11 = new XYZ(xyz10.X - AssistFunc.mmToFeet(dbOpeningBase2.SectionParameter.Parameter2 / 2.0), xyz10.Y + AssistFunc.mmToFeet(dbOpeningBase2.SectionParameter.Parameter1 / 2.0), xyz10.Z);
								XYZ xyz12 = new XYZ(xyz10.X + AssistFunc.mmToFeet(dbOpeningBase2.SectionParameter.Parameter2 / 2.0), xyz10.Y + AssistFunc.mmToFeet(dbOpeningBase2.SectionParameter.Parameter1 / 2.0), xyz10.Z);
								XYZ xyz13 = new XYZ(xyz10.X + AssistFunc.mmToFeet(dbOpeningBase2.SectionParameter.Parameter2 / 2.0), xyz10.Y - AssistFunc.mmToFeet(dbOpeningBase2.SectionParameter.Parameter1 / 2.0), xyz10.Z);
								XYZ xyz14 = new XYZ(xyz10.X - AssistFunc.mmToFeet(dbOpeningBase2.SectionParameter.Parameter2 / 2.0), xyz10.Y - AssistFunc.mmToFeet(dbOpeningBase2.SectionParameter.Parameter1 / 2.0), xyz10.Z);
								Line line5 = uiApp.ActiveUIDocument.Document.CreatYJKLine(xyz14, xyz11, true);
								Line line6 = uiApp.ActiveUIDocument.Document.CreatYJKLine(xyz11, xyz12, true);
								Line line7 = uiApp.ActiveUIDocument.Document.CreatYJKLine(xyz12, xyz13, true);
								Line line8 = uiApp.ActiveUIDocument.Document.CreatYJKLine(xyz13, xyz14, true);
								list2.AddRange(line5.Tessellate());
								list2.AddRange(line6.Tessellate());
								list2.AddRange(line7.Tessellate());
								list2.AddRange(line8.Tessellate());
							}
						}
						XYZ xyz15 = list2[0];
						XYZ xyz16 = list2[0];
						double x3 = xyz15.X;
						double y3 = xyz15.Y;
						double x4 = xyz16.X;
						double y4 = xyz16.Y;
						foreach (XYZ xyz17 in list2)
						{
							if (xyz17.X < x3)
							{
								x3 = xyz17.X;
							}
							if (xyz17.Y < y3)
							{
								y3 = xyz17.Y;
							}
							if (xyz17.X > x4)
							{
								x4 = xyz17.X;
							}
							if (xyz17.Y > y4)
							{
								y4 = xyz17.Y;
							}
						}
						xyz15 = new XYZ(x3, y3, xyz15.Z);
						xyz16 = new XYZ(x4, y4, xyz16.Z);
						XYZ basePt = DbOpeningBase.TransformPoint(DbOpeningBase.Midpoint(xyz15, xyz16), identity2);
						BoxParameter bp2;
						if (isBox)
						{
							double num3 = (double)((int)AssistFunc.feetToMM(xyz16.Y - xyz15.Y) / 2) + exLenght;
							double num4 = (double)((int)AssistFunc.feetToMM(xyz16.X - xyz15.X) / 2) + exLenght;
							bp2 = new BoxParameter(num3, num3, num4, num4);
						}
						else
						{
							bp2 = new BoxParameter((double)((int)AssistFunc.feetToMM(xyz15.DistanceTo(xyz16)) / 2) + exLenght);
						}
						result = new DbFloorToBeOpened(oList[0].mProjectId, basePt, elementId2.IntegerValue, -1, new SectionParameter(0.0, 0.0), bp2, CutType.eOther, HostType.eFloor, oList[0].Level);
					}
				}
				else
				{
					result = oList[0];
				}
			}
			catch (Exception ex)
			{
				throw ex;
			}
			return result;
		}

		private static Schema GetSchema(Autodesk.Revit.DB.Document doc)
		{
			Schema schema = Schema.Lookup(DbOpeningBase.DataGuid);
			if (schema == null)
			{
				SubTransaction subTransaction = new SubTransaction(doc);
				try
				{
					subTransaction.Start();
					SchemaBuilder schemaBuilder = new SchemaBuilder(DbOpeningBase.DataGuid);
					schemaBuilder.SetSchemaName("OpeningDataSchema");
					schemaBuilder.AddSimpleField("OpeningGuid", typeof(string));
					schemaBuilder.AddSimpleField("IsTag", typeof(bool));
					schemaBuilder.Finish();
					subTransaction.Commit();
				}
				catch
				{
					subTransaction.RollBack();
				}
			}
			return schema;
		}

		public static string WriteData(Element elem, Guid guid, bool isTag, Autodesk.Revit.DB.Document doc)
		{
			string result = "";
			SubTransaction subTransaction = new SubTransaction(doc);
			try
			{
				subTransaction.Start();
				Schema schema = DbOpeningBase.GetSchema(doc);
				Entity entity = new Entity(schema);
				Field field = schema.GetField("OpeningGuid");
				Field field2 = schema.GetField("IsTag");
				entity.Set<string>(field, guid.ToString());
				entity.Set<bool>(field2, isTag);
				elem.SetEntity(entity);
				subTransaction.Commit();
			}
			catch
			{
				subTransaction.RollBack();
			}
			return result;
		}

		public static void ReadData(Element elem, ref Guid guid, ref bool isTag)
		{
			try
			{
				Entity entity = elem.GetEntity(Schema.Lookup(DbOpeningBase.DataGuid));
				if (entity != null)
				{
					guid = new Guid(entity.Get<string>(Schema.Lookup(DbOpeningBase.DataGuid).GetField("OpeningGuid")));
					isTag = entity.Get<bool>(Schema.Lookup(DbOpeningBase.DataGuid).GetField("IsTag"));
				}
			}
			catch
			{
			}
		}

		public override int GetHashCode()
		{
			return base.GetHashCode();
		}

		protected virtual string GetSectionString()
		{
			if (this.mParameter.SectionType == DBService.SectionType.Arc)
			{
				return this.mParameter.Parameter1.ToString("F0");
			}
			return this.mParameter.Parameter2.ToString("F0") + "X" + this.mParameter.Parameter1.ToString("F0");
		}

		protected ViewPlan GetViewPlanByName(Autodesk.Revit.DB.Document doc)
		{
			IEnumerable<ViewPlan> enumerable = (from Autodesk.Revit.DB.ViewPlan e in new FilteredElementCollector(doc).OfClass(typeof(ViewPlan))
			where !e.IsTemplate
			select e).ToList<ViewPlan>();
			ViewPlan result = null;
			foreach (ViewPlan viewPlan in enumerable)
			{
				if (viewPlan.ViewName == this.LevelString + "(洞图)")
				{
					result = viewPlan;
					break;
				}
			}
			return result;
		}

		protected XYZ GetCurveInterPoint(Curve cv1, Curve cv2)
		{
			try
			{
				IntersectionResultArray intersectionResultArray = null;
                if ((int)cv1.Intersect(cv2, out intersectionResultArray) == 8 && intersectionResultArray != null && intersectionResultArray.Size > 0)
				{
					return intersectionResultArray.get_Item(0).XYZPoint;
				}
			}
			catch
			{
			}
			return null;
		}

		protected List<ModelCurve> CreateRectOpeningCvs(Autodesk.Revit.DB.Document doc, string strOpeningGUID, double dHalfW, double dHalfH, SketchPlane sketchPlane)
		{
			Transaction transaction = new Transaction(doc, "CreateOpeningTagGroup");
			transaction.Start();
			try
			{
				XYZ origin = sketchPlane.GetPlane().Origin;
				XYZ xvec = sketchPlane.GetPlane().XVec;
				XYZ yvec = sketchPlane.GetPlane().YVec;
				XYZ xyz = origin - xvec * dHalfW;
				xyz += yvec * dHalfH;
				XYZ xyz2 = xyz + xvec * dHalfW * 2.0;
				XYZ xyz3 = xyz2 - yvec * dHalfH * 2.0;
				XYZ xyz4 = xyz3 - xvec * dHalfW * 2.0;
				List<ModelCurve> list = new List<ModelCurve>();
				ModelCurve item = doc.Create.NewModelCurve(Line.CreateBound(xyz, xyz4), sketchPlane);
				ModelCurve item2 = doc.Create.NewModelCurve(Line.CreateBound(xyz4, xyz3), sketchPlane);
				ModelCurve item3 = doc.Create.NewModelCurve(Line.CreateBound(xyz3, xyz2), sketchPlane);
				ModelCurve item4 = doc.Create.NewModelCurve(Line.CreateBound(xyz2, xyz), sketchPlane);
				list.Add(item);
				list.Add(item2);
				list.Add(item3);
				list.Add(item4);
				transaction.Commit();
				return list;
			}
			catch
			{
				transaction.RollBack();
			}
			return null;
		}

		protected List<ModelCurve> CreateCircleOpeningCvs(Autodesk.Revit.DB.Document doc, string strOpeningGUID, double dR, SketchPlane sketchPlane)
		{
			Transaction transaction = new Transaction(doc, "CreateOpeningTagGroup");
			transaction.Start();
			try
			{
				XYZ origin = sketchPlane.GetPlane().Origin;
				XYZ xvec = sketchPlane.GetPlane().XVec;
				XYZ yvec = sketchPlane.GetPlane().YVec;
				XYZ xyz = origin + yvec * dR;
				XYZ xyz2 = origin - yvec * dR;
				XYZ xyz3 = origin - xvec * dR;
				XYZ xyz4 = origin + xvec * dR;
				List<ModelCurve> list = new List<ModelCurve>();
				Curve curve = Arc.Create(xyz3, xyz4, xyz);
				Curve curve2 = Arc.Create(xyz3, xyz4, xyz2);
				ModelCurve item = doc.Create.NewModelCurve(curve, sketchPlane);
				ModelCurve item2 = doc.Create.NewModelCurve(curve2, sketchPlane);
				list.Add(item);
				list.Add(item2);
				transaction.Commit();
				return list;
			}
			catch
			{
				transaction.RollBack();
			}
			return null;
		}

		public static FamilySymbol LoadOpeningFamily(Autodesk.Revit.DB.Document doc, string strFamilyName)
		{
			FamilySymbol familySymbol = YJKRevitTools.GetFamilySymbol(strFamilyName, doc);
			if (familySymbol != null)
			{
				return familySymbol;
			}
			string text = Path.Combine(FamilyLibDatabase.GetDefFamilyLibPath(), string.Concat(new string[]
			{
				"Family\\",
				RevitVersion.Version,
				"\\Opening\\",
				strFamilyName,
				".rfa"
			}));
			Family family = null;
			try
			{
				Transaction transaction = new Transaction(doc, "CreateOpening");
				transaction.Start();
				doc.LoadFamily(text, out family);
				transaction.Commit();
			}
			catch (Exception ex)
			{
				YJKMessageBox.Show(ex.Message);
				return null;
			}
			return family.GetSymbols().FirstOrDefault<FamilySymbol>();
		}

		public static string SynergyDataPath = "";

		public static Guid OpeningAppGuid = new Guid("354cda5a-e6c5-4c3f-a9ef-b3222116b8c8");

		protected int mHostId;

		protected int mPipeId;

		protected IDatabase mDatabase;

		protected Guid mGuid;

		protected int mProjectId;

		protected SectionParameter mParameter;

		protected string m_strDrivePipeTypeName = "无";

		private OpeningStatus mStatus;

		protected XYZ mPt;

		[Browsable(false)]
		public bool IsValid = true;

		public const double _epsDouble = 1E-09;

		private static Guid DataGuid = new Guid("352cda5a-e6c5-4c2f-a9ef-b1273376b8c8");

		public static Guid guidOpening3D = new Guid("5c302a8d-670b-415e-83c9-115f9fee0043");

		public static string m_strSharedParaOpeningMajor = "专业";

		public static string m_strSharedParaOpeningElevTop = "顶部标高";

		public static string m_strSharedParaOpeningElevCenter = "中心标高";

		public static string m_strSharedParaOpeningElevBottom = "底部标高";

		public static string m_strSharedParaOpeningElev = "标注标高";

		public static string m_strSharedParaOpeningSize = "尺寸";
	}
}
